//
//  QRCodeViewController.swift
//  微博
//
//  Created by expai on 16/5/9.
//  Copyright © 2016年 guangJun.com.cn. All rights reserved.
//

import UIKit
import AVFoundation

class QRCodeViewController: UIViewController, UITabBarDelegate {

    //冲击波视图顶部约束
    @IBOutlet weak var scanLineCons: NSLayoutConstraint!
    //冲击波视图
    @IBOutlet weak var scanLineView: UIImageView!
    
      
    @IBOutlet weak var qrcodeBorderheight: NSLayoutConstraint!
    //底部视图
    @IBOutlet weak var customTabBar: UITabBar!
    
    
    @IBAction func closeBtnClick(sender: AnyObject) {
        dismissViewControllerAnimated(true) { 
            
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        customTabBar.selectedItem = customTabBar.items![0]
        customTabBar.delegate = self
    }

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        
        //开始动画
        startAnimation()
        
        //开始扫描
        startScan()
        
    }
    
    //扫描二维码
    private func startScan(){
    
        //1.判断能否将输入添加到会话中
        if !session.canAddInput(deviceInput)
        {
            return
        }
        //2.判断是否能够将输出添加到会话中
        if !session.canAddOutput(output)
        {
            return
        }
        //3.将输入和输出都添加到会话中
        session.addInput(deviceInput)
        print(output.availableMetadataObjectTypes)
        session.addOutput(output)
        print(output.availableMetadataObjectTypes)
        
        //4.设置输出能够解析的数据类型
        output.metadataObjectTypes = output.availableMetadataObjectTypes
        print(output.availableMetadataObjectTypes)
        //5.设置输出对象的代理，只要解析成功就会通知代理
        output.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
        
        //添加预览图层
        view.layer.insertSublayer(previewLayer, atIndex: 0)
        
        //添加绘制图层到预览图层上
        previewLayer.addSublayer(drawLayer)

        //6.告诉session 开始扫描
        session.startRunning()
    }
    
    //执行动画
    private func startAnimation()
    {
        self.scanLineCons.constant = -self.qrcodeBorderheight.constant
        self.scanLineView.layoutIfNeeded()
        
        //执行冲击波动画
        UIView.animateWithDuration(2.0) { 
            //修改约束
            self.scanLineCons.constant = self.qrcodeBorderheight.constant
            //设置动画指定的次数
            UIView.setAnimationRepeatCount(MAXFLOAT)
            //强制更新界面
            self.scanLineView.layoutIfNeeded()
        }
    }
    
    //代理方法
    func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem) {
        if(item.tag == 1){
            self.qrcodeBorderheight.constant = 300
        }
        else{
            self.qrcodeBorderheight.constant = 150
        }
        //2停止动画
        self.scanLineView.layer.removeAllAnimations()
        //3.重新开始动画
        startAnimation()
    }
    
    //会话
    private lazy var session : AVCaptureSession = AVCaptureSession()
    
    //拿到输入设备
    private lazy var deviceInput : AVCaptureDeviceInput? = {
        //获取摄像头
        let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
        do {
            //创建输入对象
            let input = try AVCaptureDeviceInput(device: device)
            return input
        }catch
        {
            print(error)
            return nil
        }
    }()
    
    //创建输出对象
    private lazy var output: AVCaptureMetadataOutput = AVCaptureMetadataOutput()
    
    
    //创建预览图层
    private lazy var previewLayer: AVCaptureVideoPreviewLayer = {
        let layer = AVCaptureVideoPreviewLayer(session: self.session)
        layer.frame = UIScreen.mainScreen().bounds
        return layer
    }()
    
    //创建用于绘制边线的图层
    private lazy var drawLayer: CALayer = {
        let layer = CALayer()
        layer.frame = UIScreen.mainScreen().bounds
        return layer
    }()
}

extension QRCodeViewController: AVCaptureMetadataOutputObjectsDelegate
{
    
    //只要解析到数据就会调用
    func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
        
        //清除图层
        clearConers()
        //获取扫描到的数据
        //注意：要使用stringValue
        print(metadataObjects.last?.stringValue)
        
        //获取扫描到的二维码的位置
        for object in metadataObjects {
            
            // 2.1.1判断当前获取到的数据, 是否是机器可识别的类型
            if object is AVMetadataMachineReadableCodeObject
            {
//                let codeObject =previewLayer.transformedMetadataObjectForMetadataObject(object as! AVMetadataObject) as! AVMetadataMachineReadableCodeObject)
                 let codeObject = previewLayer.transformedMetadataObjectForMetadataObject(object as! AVMetadataObject) as! AVMetadataMachineReadableCodeObject
                
                print(codeObject)
//                drawCorners(codeObject)
                //绘制图形
                drawCorners(codeObject)
            }
        }
        
    }
    
    private func drawCorners(codeObject:AVMetadataMachineReadableCodeObject)
    {
        if codeObject.corners.isEmpty
        {
            return
        }
        
        //创建一个图层
        let layer = CAShapeLayer()
        layer.lineWidth = 4.0
        layer.strokeColor = UIColor.grayColor().CGColor
        layer.fillColor = UIColor.clearColor().CGColor
        
        //创建路径
        let path = UIBezierPath()
        var point = CGPointZero
        var index: Int = 0
        
        // 从corners数组中取出第0个元素, 将这个字典中的x/y赋值给point
        CGPointMakeWithDictionaryRepresentation((codeObject.corners[index++] as! CFDictionaryRef), &point)
        path.moveToPoint(point)
        
        //移动到其他的点
        while index < codeObject.corners.count
        {
            CGPointMakeWithDictionaryRepresentation((codeObject.corners[index++] as! CFDictionaryRef), &point)
            path.addLineToPoint(point)
        }
        //关闭路径
        path.closePath()
        
        //绘制路径
        layer.path = path.CGPath
        
        // 3.将绘制好的图层添加到drawLayer上
        drawLayer.addSublayer(layer)
        
    }

    //清空边线
    private func clearConers()
    {
        //1.判断drawLayer上是否有其他图层
        if drawLayer.sublayers == nil || drawLayer.sublayers?.count == 0
        {
            return
        }
        
        //2.移除所有子图层
        for subLayer in drawLayer.sublayers! {
            subLayer.removeFromSuperlayer()
        }
    }
}